home *** CD-ROM | disk | FTP | other *** search
/ Aminet 43 / Aminet 43 (2001)(GTI - Schatztruhe)[!][Jun 2001].iso / Aminet / comm / mail / YAM22src.lha / YAM_rexx.c < prev    next >
C/C++ Source or Header  |  2000-11-03  |  19KB  |  871 lines

  1. /*
  2.  * Source generated with ARexxBox 1.12 (May 18 1993)
  3.  * which is Copyright (c) 1992,1993 Michael Balzer
  4.  */
  5.  
  6. #include <exec/types.h>
  7. #include <exec/memory.h>
  8. #include <dos/dos.h>
  9. #include <rexx/storage.h>
  10. #include <rexx/rxslib.h>
  11.  
  12. #ifdef __GNUC__
  13. /* GCC needs all struct defs */
  14. #include <dos/exall.h>
  15. #include <graphics/graphint.h>
  16. #include <intuition/classes.h>
  17. #include <devices/keymap.h>
  18. #include <exec/semaphores.h>
  19. #endif
  20.  
  21. #include <clib/alib_protos.h>
  22. #include <clib/exec_protos.h>
  23. #include <clib/dos_protos.h>
  24. #include <clib/rexxsyslib_protos.h>
  25.  
  26. #ifndef __NO_PRAGMAS
  27.  
  28. #ifdef AZTEC_C
  29. #include <pragmas/exec_lib.h>
  30. #include <pragmas/dos_lib.h>
  31. #include <pragmas/rexxsyslib_lib.h>
  32. #endif
  33.  
  34. #ifdef LATTICE
  35. #include <pragmas/exec_pragmas.h>
  36. #include <pragmas/dos_pragmas.h>
  37. #include <pragmas/rexxsyslib_pragmas.h>
  38. #endif
  39.  
  40. #endif /* __NO_PRAGMAS */
  41.  
  42. #include <stdlib.h>
  43. #include <stdio.h>
  44. #include <string.h>
  45. #include <ctype.h>
  46.  
  47. #ifdef LATTICE
  48. #undef toupper
  49. #define inline __inline
  50. #endif
  51.  
  52. #ifdef __GNUC__
  53. #undef toupper
  54. static inline char toupper( char c )
  55. {
  56.    return( islower(c) ? c - 'a' + 'A' : c );
  57. }
  58. #endif
  59.  
  60. #ifdef AZTEC_C
  61. #define inline
  62. #endif
  63.  
  64. #include <dos/rdargs.h>
  65.  
  66. #include "YAM_rexx.h"
  67.  
  68. struct rxs_stemnode
  69. {
  70.    struct rxs_stemnode *succ;
  71.    char *name;
  72.    char *value;
  73. };
  74.  
  75.  
  76. extern struct ExecBase *SysBase;
  77. extern struct DosLibrary *DOSBase;
  78. extern struct RxsLib *RexxSysBase;
  79.  
  80. void (*ARexxResultHook)( struct RexxHost *, struct RexxMsg * ) = NULL;
  81.  
  82.  
  83.  
  84. void ReplyRexxCommand(
  85.    struct RexxMsg *rexxmessage,
  86.    long        primary,
  87.    long        secondary,
  88.    char        *result )
  89. {
  90.    if( rexxmessage->rm_Action & RXFF_RESULT )
  91.    {
  92.       if( primary == 0 )
  93.       {
  94.          secondary = result
  95.             ? (long) CreateArgstring( result, strlen(result) )
  96.             : (long) NULL;
  97.       }
  98.       else
  99.       {
  100.          char buf[16];
  101.          
  102.          if( primary > 0 )
  103.          {
  104.             sprintf( buf, "%ld", secondary );
  105.             result = buf;
  106.          }
  107.          else
  108.          {
  109.             primary = -primary;
  110.             result = (char *) secondary;
  111.          }
  112.          
  113.          SetRexxVar( (struct Message *) rexxmessage,
  114.             "RC2", result, strlen(result) );
  115.          
  116.          secondary = 0;
  117.       }
  118.    }
  119.    else if( primary < 0 )
  120.       primary = -primary;
  121.    
  122.    rexxmessage->rm_Result1 = primary;
  123.    rexxmessage->rm_Result2 = secondary;
  124.    ReplyMsg( (struct Message *) rexxmessage );
  125. }
  126.  
  127.  
  128. void FreeRexxCommand( struct RexxMsg *rexxmessage )
  129. {
  130.    if( !rexxmessage->rm_Result1 && rexxmessage->rm_Result2 )
  131.       DeleteArgstring( (char *) rexxmessage->rm_Result2 );
  132.  
  133.    if( rexxmessage->rm_Stdin &&
  134.       rexxmessage->rm_Stdin != Input() )
  135.       Close( rexxmessage->rm_Stdin );
  136.  
  137.    if( rexxmessage->rm_Stdout &&
  138.       rexxmessage->rm_Stdout != rexxmessage->rm_Stdin &&
  139.       rexxmessage->rm_Stdout != Output() )
  140.       Close( rexxmessage->rm_Stdout );
  141.  
  142.    DeleteArgstring( (char *) ARG0(rexxmessage) );
  143.    DeleteRexxMsg( rexxmessage );
  144. }
  145.  
  146.  
  147. struct RexxMsg *CreateRexxCommand( struct RexxHost *host, char *buff, BPTR fh )
  148. {
  149.    struct RexxMsg *rexx_command_message;
  150.  
  151.    if( (rexx_command_message = CreateRexxMsg( host->port,
  152.       rexx_extension, host->port->mp_Node.ln_Name)) == NULL )
  153.    {
  154.       return( NULL );
  155.    }
  156.  
  157.    if( (rexx_command_message->rm_Args[0] =
  158.       CreateArgstring(buff,strlen(buff))) == NULL )
  159.    {
  160.       DeleteRexxMsg(rexx_command_message);
  161.       return( NULL );
  162.    }
  163.  
  164.    rexx_command_message->rm_Action = RXCOMM | RXFF_RESULT;
  165.    rexx_command_message->rm_Stdin  = fh;
  166.    rexx_command_message->rm_Stdout = fh;
  167.    
  168.    return( rexx_command_message );
  169. }
  170.  
  171.  
  172. struct RexxMsg *CommandToRexx( struct RexxHost *host, struct RexxMsg *rexx_command_message )
  173. {
  174.    struct MsgPort *rexxport;
  175.    
  176.    Forbid();
  177.  
  178.    if( (rexxport = FindPort(RXSDIR)) == NULL )
  179.    {
  180.       Permit();
  181.       return( NULL );
  182.    }
  183.  
  184.    PutMsg( rexxport, &rexx_command_message->rm_Node );
  185.    
  186.    Permit();
  187.    
  188.    ++host->replies;
  189.    return( rexx_command_message );
  190. }
  191.  
  192.  
  193. struct RexxMsg *SendRexxCommand( struct RexxHost *host, char *buff, BPTR fh )
  194. {
  195.    struct RexxMsg *rcm;
  196.    
  197.    if( rcm = CreateRexxCommand(host, buff, fh) )
  198.       return CommandToRexx( host, rcm );
  199.    else
  200.       return NULL;
  201. }
  202.  
  203.  
  204. void CloseDownARexxHost( struct RexxHost *host )
  205. {
  206.    struct RexxMsg *rexxmsg;
  207.    
  208.    if( host->port )
  209.    {
  210.       /* Port abmelden */
  211.       RemPort( host->port );
  212.       
  213.       /* Auf noch ausstehende Replies warten */
  214.       while( host->replies > 0 )
  215.       {
  216.          WaitPort( host->port );
  217.          
  218.          while( rexxmsg = (struct RexxMsg *) GetMsg(host->port) )
  219.          {
  220.             if( rexxmsg->rm_Node.mn_Node.ln_Type == NT_REPLYMSG )
  221.             {
  222.                if( !rexxmsg->rm_Args[15] )
  223.                {
  224.                   /* Reply zu einem SendRexxCommand()-Call */
  225.                   if( ARexxResultHook )
  226.                      ARexxResultHook( host, rexxmsg );
  227.                }
  228.                
  229.                FreeRexxCommand( rexxmsg );
  230.                --host->replies;
  231.             }
  232.             else
  233.                ReplyRexxCommand( rexxmsg, -20, (long) "Host closing down", NULL );
  234.          }
  235.       }
  236.       
  237.       /* MsgPort leeren */
  238.       while( rexxmsg = (struct RexxMsg *) GetMsg(host->port) )
  239.          ReplyRexxCommand( rexxmsg, -20, (long) "Host closing down", NULL );
  240.       
  241.       if( !(host->flags & ARB_HF_USRMSGPORT) )
  242.          DeleteMsgPort( host->port );
  243.    }
  244.    
  245.    if( host->rdargs ) FreeDosObject( DOS_RDARGS, host->rdargs );
  246.    FreeVec( host );
  247. }
  248.  
  249.  
  250. struct RexxHost *SetupARexxHost( char *basename, struct MsgPort *usrport )
  251. {
  252.    struct RexxHost *host;
  253.    int ext = 0;
  254.    
  255.    if( !basename )
  256.       basename = RexxPortBaseName;
  257.    else if( !*basename )
  258.       basename = RexxPortBaseName;
  259.    
  260.    if( !(host = AllocVec(sizeof *host, MEMF_CLEAR)) )
  261.       return NULL;
  262.    
  263.    strcpy( host->portname, basename );
  264.    
  265.    if( usrport )
  266.    {
  267.       host->port   = usrport;
  268.       host->flags |= ARB_HF_USRMSGPORT;
  269.    }
  270.    else if( !(host->port = CreateMsgPort()) )
  271.    {
  272.       FreeVec( host );
  273.       return NULL;
  274.    }
  275.    else
  276.    {
  277.       host->port->mp_Node.ln_Pri = 0;
  278.    }
  279.    
  280.    Forbid();
  281.    
  282.    while( FindPort(host->portname) )
  283.       sprintf( host->portname, "%s.%d", basename, ++ext );
  284.    
  285.    host->port->mp_Node.ln_Name = host->portname;
  286.    AddPort( host->port );
  287.    
  288.    Permit();
  289.    
  290.    if( !(host->rdargs = AllocDosObject(DOS_RDARGS, NULL)) )
  291.    {
  292.       RemPort( host->port );
  293.       if( !usrport ) DeleteMsgPort( host->port );
  294.       FreeVec( host );
  295.       return NULL;
  296.    }
  297.    
  298.    host->rdargs->RDA_Flags = RDAF_NOPROMPT;
  299.    
  300.    return( host );
  301. }
  302.  
  303.  
  304. /* StateMachine für FindRXCommand() */
  305.  
  306. static inline char *scmp( char *inp, char *str )
  307. {
  308.    while( *str && *inp )
  309.       if( *inp++ != *str++ )
  310.          return NULL;
  311.    
  312.    /* Reststring zurückgeben */
  313.    return inp;
  314. }
  315.  
  316. static int find( char *input )
  317. {
  318.    struct arb_p_state *st = arb_p_state;
  319.    struct arb_p_link *ad;
  320.    char *ni, tmp[36], *s;
  321.    
  322.    ni = tmp;
  323.    while( *input && ni-tmp < 32 )
  324.       *ni++ = toupper( *input++ );
  325.    *ni = 0;
  326.    input = tmp;
  327.    
  328.    while( *input )
  329.    {
  330.       /* Terminalzustand erreicht? */
  331.       if( !st->pa )
  332.       {
  333.          if( *input )
  334.             return -1;
  335.          else
  336.             return st->cmd;
  337.       }
  338.       
  339.       /* Wo geht's weiter? */
  340.       ni = 0;
  341.       for( ad = st->pa; s = ad->str; ad++ )
  342.       {
  343.          /* die Links sind absteigend sortiert */
  344.          if( *input > *s )
  345.             break;
  346.          
  347.          if( *input == *s )
  348.             if( ni = scmp(input+1, s+1) )
  349.                break;
  350.       }
  351.       
  352.       /* Nirgends... */
  353.       if( !ni )
  354.          return -1;
  355.       
  356.       /* Zustandsüberführung */
  357.       st = arb_p_state + ad->dst;
  358.       input = ni;
  359.    }
  360.    
  361.    return st->cmd;
  362. }
  363.  
  364. struct rxs_command *FindRXCommand( char *com )
  365. {
  366.    int cmd;
  367.    
  368.    cmd = find( com );
  369.    
  370.    if( cmd == -1 )
  371.       return NULL;
  372.    else
  373.       return( rxs_commandlist + cmd );
  374. }
  375.  
  376.  
  377. static struct rxs_command *ParseRXCommand( char **arg )
  378. {
  379.    char com[256], *s, *t;
  380.    
  381.    s = *arg;
  382.    t = com;
  383.    
  384.    while( *s && *s != ' ' && *s != '\n' )
  385.       *t++ = *s++;
  386.    
  387.    *t = '\0';
  388.    while( *s == ' ' ) ++s;
  389.    *arg = s;
  390.    
  391.    return( FindRXCommand( com ) );
  392. }
  393.  
  394.  
  395. static char *CreateVAR( struct rxs_stemnode *stem )
  396. {
  397.    char *var;
  398.    struct rxs_stemnode *s;
  399.    long size = 0;
  400.    
  401.    if( !stem || stem == (struct rxs_stemnode *) -1L )
  402.       return( (char *) stem );
  403.    
  404.    for( s = stem; s; s = s->succ )
  405.       size += strlen( s->value ) + 1;
  406.    
  407.    if( !(var = AllocVec( size + 1, MEMF_ANY )) )
  408.       return( (char *) -1 );
  409.    
  410.    *var = '\0';
  411.    
  412.    for( s = stem; s; s = s->succ )
  413.    {
  414.       strcat( var, s->value );
  415.       if( s->succ )
  416.          strcat( var, " " );
  417.    }
  418.    
  419.    return( var );
  420. }
  421.  
  422.  
  423. static struct rxs_stemnode *new_stemnode( struct rxs_stemnode **first, struct rxs_stemnode **old )
  424. {
  425.    struct rxs_stemnode *new;
  426.    
  427.    if( !(new = AllocVec(sizeof(struct rxs_stemnode), MEMF_CLEAR)) )
  428.    {
  429.       return( NULL );
  430.    }
  431.    else
  432.    {
  433.       if( *old )
  434.       {
  435.          (*old)->succ = new;
  436.          (*old) = new;
  437.       }
  438.       else
  439.       {
  440.          *first = *old = new;
  441.       }
  442.    }
  443.    
  444.    return( new );
  445. }
  446.  
  447.  
  448. static void free_stemlist( struct rxs_stemnode *first )
  449. {
  450.    struct rxs_stemnode *next;
  451.    
  452.    if( (long) first == -1 )
  453.       return;
  454.    
  455.    for( ; first; first = next )
  456.    {
  457.       next = first->succ;
  458.       if( first->name  ) FreeVec( first->name );
  459.       if( first->value ) FreeVec( first->value );
  460.       FreeVec( first );
  461.    }
  462. }
  463.  
  464.  
  465. char *StrDup( char *s )
  466. {
  467.    char *t = AllocVec( strlen(s)+1, MEMF_ANY );
  468.    if( t ) strcpy( t, s );
  469.    return t;
  470. }
  471.  
  472.  
  473. static struct rxs_stemnode *CreateSTEM( struct rxs_command *rxc, LONG *resarray, char *stembase )
  474. {
  475.    struct rxs_stemnode *first = NULL, *old = NULL, *new;
  476.    char resb[512], *rs, *rb;
  477.    char longbuff[16];
  478.    
  479.    rb = resb;
  480.    if( stembase )
  481.    {
  482.       while( *stembase )
  483.          *rb++ = toupper( *stembase++ );
  484.    }
  485.    *rb = '\0';
  486.    
  487.    rb = resb + strlen(resb);
  488.    rs = rxc->results;
  489.    
  490.    while( *rs )
  491.    {
  492.       char *t = rb;
  493.       BOOL optn = FALSE, optm = FALSE;
  494.       
  495.       while( *rs && *rs != ',' )
  496.       {
  497.          if( *rs == '/' )
  498.          {
  499.             ++rs;
  500.             if( *rs == 'N' ) optn = TRUE;
  501.             else if( *rs == 'M' ) optm = TRUE;
  502.          }
  503.          else
  504.             *t++ = *rs;
  505.          
  506.          ++rs;
  507.       }
  508.       
  509.       if( *rs == ',' ) ++rs;
  510.       *t = '\0';
  511.       
  512.       /*
  513.        * Resultat(e) erzeugen
  514.        */
  515.       
  516.       if( !*resarray )
  517.       {
  518.          ++resarray;
  519.          continue;
  520.       }
  521.       
  522.       if( optm )
  523.       {
  524.          long *r, index = 0;
  525.          LONG **subarray = (LONG **) *resarray++;
  526.          struct rxs_stemnode *countnd;
  527.          
  528.          /* Anzahl der Elemente */
  529.          
  530.          if( !(new = new_stemnode(&first, &old)) )
  531.          {
  532.             free_stemlist( first );
  533.             return( (struct rxs_stemnode *) -1L );
  534.          }
  535.          countnd = new;
  536.          
  537.          /* Die Elemente selbst */
  538.          
  539.          while( r = *subarray++ )
  540.          {
  541.             if( !(new = new_stemnode(&first, &old)) )
  542.             {
  543.                free_stemlist( first );
  544.                return( (struct rxs_stemnode *) -1L );
  545.             }
  546.             
  547.             sprintf( t, ".%ld", index++ );
  548.             new->name = StrDup( resb );
  549.             
  550.             if( optn )
  551.             {
  552.                sprintf( longbuff, "%ld", *r );
  553.                new->value = StrDup( longbuff );
  554.             }
  555.             else
  556.             {
  557.                new->value = StrDup( (char *) r );
  558.             }
  559.          }
  560.          
  561.          /* Die Count-Node */
  562.          
  563.          strcpy( t, ".COUNT" );
  564.          countnd->name = StrDup( resb );
  565.          
  566.          sprintf( longbuff, "%ld", index );
  567.          countnd->value = StrDup( longbuff );
  568.       }
  569.       else
  570.       {
  571.          /* Neue Node anlegen */
  572.          if( !(new = new_stemnode(&first, &old)) )
  573.          {
  574.             free_stemlist( first );
  575.             return( (struct rxs_stemnode *) -1L );
  576.          }
  577.          
  578.          new->name = StrDup( resb );
  579.          
  580.          if( optn )
  581.          {
  582.             sprintf( longbuff, "%ld", *((long *) *resarray) );
  583.             new->value = StrDup( longbuff );
  584.             ++resarray;
  585.          }
  586.          else
  587.          {
  588.             new->value = StrDup( (char *) (*resarray++) );
  589.          }
  590.       }
  591.    }
  592.    
  593.    return( first );
  594. }
  595.  
  596.  
  597. void DoRXCommand( struct RexxHost *host, struct RexxMsg *rexxmsg )
  598. {
  599.    struct rxs_command *rxc;
  600.    char *argb = NULL, *arg;
  601.    
  602.    LONG *array = NULL;
  603.    LONG *argarray;
  604.    LONG *resarray;
  605.    
  606.    char *cargstr = NULL;
  607.    long rc=20, rc2=0;
  608.    char *result = NULL;
  609.    
  610.    if( !(argb = AllocVec(strlen((char *) ARG0(rexxmsg)) + 2, MEMF_ANY)) )
  611.    {
  612.       rc2 = ERROR_NO_FREE_STORE;
  613.       goto drc_cleanup;
  614.    }
  615.    
  616.    /* welches Kommando? */
  617.    
  618.    strcpy( argb, (char *) ARG0(rexxmsg) );
  619.    strcat( argb, "\n" );
  620.    arg = argb;
  621.    
  622.    if( !( rxc = ParseRXCommand( &arg ) ) )
  623.    {
  624.       if( arg = ExpandRXCommand( host, (char *) ARG0(rexxmsg) ) )
  625.       {
  626.          FreeVec( argb );
  627.          if( !(argb = AllocVec( strlen(arg) + 2, MEMF_ANY )) )
  628.          {
  629.             rc2 = ERROR_NO_FREE_STORE;
  630.             goto drc_cleanup;
  631.          }
  632.          
  633.          strcpy( argb, arg );
  634.          strcat( argb, "\n" );
  635.          FreeVec( arg );
  636.          arg = argb;
  637.          
  638.          rxc = ParseRXCommand( &arg );
  639.       }
  640.    }
  641.    
  642.    if( !rxc )
  643.    {
  644.       /* Msg an ARexx schicken, vielleicht existiert ein Skript */
  645.       struct RexxMsg *rm;
  646.       
  647.       if( rm = CreateRexxCommand(host, (char *) ARG0(rexxmsg), NULL) )
  648.       {
  649.          /* Original-Msg merken */
  650.          rm->rm_Args[15] = (STRPTR) rexxmsg;
  651.          
  652.          if( CommandToRexx(host, rm) )
  653.          {
  654.             /* Reply wird später vom Dispatcher gemacht */
  655.             if( argb ) FreeVec( argb );
  656.             return;
  657.          }
  658.          else
  659.             rc2 = ERROR_NOT_IMPLEMENTED;
  660.       }
  661.       else
  662.          rc2 = ERROR_NO_FREE_STORE;
  663.       
  664.       goto drc_cleanup;
  665.    }
  666.    
  667.    if( !(rxc->flags & ARB_CF_ENABLED) )
  668.    {
  669.       rc = -10;
  670.       rc2 = (long) "Command disabled";
  671.       goto drc_cleanup;
  672.    }
  673.    
  674.    /* Speicher für Argumente etc. holen */
  675.    
  676.    (rxc->function)( host, (void **) &array, RXIF_INIT, rexxmsg );
  677.    cargstr = AllocVec( rxc->args ? 15+strlen(rxc->args) : 15, MEMF_ANY );
  678.    
  679.    if( !array || !cargstr )
  680.    {
  681.       rc2 = ERROR_NO_FREE_STORE;
  682.       goto drc_cleanup;
  683.    }
  684.    
  685.    argarray = array + 2;
  686.    resarray = array + rxc->resindex;
  687.    
  688.    /* Argumente parsen */
  689.    
  690.    if( rxc->results )
  691.       strcpy( cargstr, "VAR/K,STEM/K" );
  692.    else
  693.       *cargstr = '\0';
  694.    
  695.    if( rxc->args )
  696.    {
  697.       if( *cargstr )
  698.          strcat( cargstr, "," );
  699.       strcat( cargstr, rxc->args );
  700.    }
  701.    
  702.    if( *cargstr )
  703.    {
  704.       host->rdargs->RDA_Source.CS_Buffer = arg;
  705.       host->rdargs->RDA_Source.CS_Length = strlen(arg);
  706.       host->rdargs->RDA_Source.CS_CurChr = 0;
  707.       host->rdargs->RDA_DAList = NULL;
  708.       host->rdargs->RDA_Buffer = NULL;
  709.       
  710.       if( !ReadArgs(cargstr, argarray, host->rdargs) )
  711.       {
  712.          rc = 10;
  713.          rc2 = IoErr();
  714.          goto drc_cleanup;
  715.       }
  716.    }
  717.    
  718.    /* Funktion aufrufen */
  719.    
  720.    (rxc->function)( host, (void **) &array, RXIF_ACTION, rexxmsg );
  721.    
  722.    rc = array[0];
  723.    rc2 = array[1];
  724.    
  725.    /* Resultat(e) auswerten */
  726.    
  727.    if( rxc->results && rc==0 &&
  728.       (rexxmsg->rm_Action & RXFF_RESULT) )
  729.    {
  730.       struct rxs_stemnode *stem, *s;
  731.       
  732.       stem = CreateSTEM( rxc, resarray, (char *)argarray[1] );
  733.       result = CreateVAR( stem );
  734.       
  735.       if( result )
  736.       {
  737.          if( argarray[0] )
  738.          {
  739.             /* VAR */
  740.             if( (long) result == -1 )
  741.             {
  742.                rc = 20;
  743.                rc2 = ERROR_NO_FREE_STORE;
  744.             }
  745.             else
  746.             {
  747.                char *rb;
  748.                
  749.                for( rb = (char *) argarray[0]; *rb; ++rb )
  750.                   *rb = toupper( *rb );
  751.                
  752.                if( SetRexxVar( (struct Message *) rexxmsg,
  753.                   *((char *)argarray[0]) ? (char *)argarray[0] : "RESULT",
  754.                   result, strlen(result) ) )
  755.                {
  756.                   rc = -10;
  757.                   rc2 = (long) "Unable to set Rexx variable";
  758.                }
  759.                
  760.                FreeVec( result );
  761.             }
  762.             
  763.             result = NULL;
  764.          }
  765.          
  766.          if( !rc && argarray[1] )
  767.          {
  768.             /* STEM */
  769.             if( (long) stem == -1 )
  770.             {
  771.                rc = 20;
  772.                rc2 = ERROR_NO_FREE_STORE;
  773.             }
  774.             else
  775.             {
  776.                for( s = stem; s; s = s->succ )
  777.                   rc |= SetRexxVar( (struct Message *) rexxmsg, s->name, s->value, strlen(s->value) );
  778.                
  779.                if( rc )
  780.                {
  781.                   rc = -10;
  782.                   rc2 = (long) "Unable to set Rexx variable";
  783.                }
  784.                
  785.                if( result && (long) result != -1 )
  786.                   FreeVec( result );
  787.             }
  788.             
  789.             result = NULL;
  790.          }
  791.          
  792.          /* Normales Resultat: Möglich? */
  793.          
  794.          if( (long) result == -1 )
  795.          {
  796.             /* Nein */
  797.             rc = 20;
  798.             rc2 = ERROR_NO_FREE_STORE;
  799.             result = NULL;
  800.          }
  801.       }
  802.       
  803.       free_stemlist( stem );
  804.    }
  805.    
  806. drc_cleanup:
  807.  
  808.    /* Nur RESULT, wenn weder VAR noch STEM */
  809.    
  810.    ReplyRexxCommand( rexxmsg, rc, rc2, result );
  811.    
  812.    /* benutzten Speicher freigeben */
  813.    
  814.    if( result ) FreeVec( result );
  815.    FreeArgs( host->rdargs );
  816.    if( cargstr ) FreeVec( cargstr );
  817.    if( array ) (rxc->function)( host, (void **) &array, RXIF_FREE, rexxmsg );
  818.    if( argb ) FreeVec( argb );
  819. }
  820.  
  821.  
  822. void ARexxDispatch( struct RexxHost *host )
  823. {
  824.    struct RexxMsg *rexxmsg;
  825.  
  826.    while( rexxmsg = (struct RexxMsg *) GetMsg(host->port) )
  827.    {
  828.       if( (rexxmsg->rm_Action & RXCODEMASK) != RXCOMM )
  829.       {
  830.          /* Keine Rexx-Message */
  831.          ReplyMsg( (struct Message *) rexxmsg );
  832.       }
  833.       else if( rexxmsg->rm_Node.mn_Node.ln_Type == NT_REPLYMSG )
  834.       {
  835.          struct RexxMsg *org = (struct RexxMsg *) rexxmsg->rm_Args[15];
  836.          
  837.          if( org )
  838.          {
  839.             /* Reply zu durchgereichter Msg */
  840.             if( rexxmsg->rm_Result1 != 0 )
  841.             {
  842.                /* Befehl unbekannt */
  843.                ReplyRexxCommand( org, 20, ERROR_NOT_IMPLEMENTED, NULL );
  844.             }
  845.             else
  846.             {
  847.                ReplyRexxCommand( org, 0, 0, (char *) rexxmsg->rm_Result2 );
  848.             }
  849.          }
  850.          else
  851.          {
  852.             /* Reply zu einem SendRexxCommand()-Call */
  853.             if( ARexxResultHook )
  854.                ARexxResultHook( host, rexxmsg );
  855.          }
  856.          
  857.          FreeRexxCommand( rexxmsg );
  858.          --host->replies;
  859.       }
  860.       else if( ARG0(rexxmsg) )
  861.       {
  862.          DoRXCommand( host, rexxmsg );
  863.       }
  864.       else
  865.       {
  866.          ReplyMsg( (struct Message *) rexxmsg );
  867.       }
  868.    }
  869. }
  870.  
  871.